package com.prefuse.visualization;

import javax.swing.JFrame;

import net.sourceforge.phpdt.internal.compiler.ast.Statement;

import prefuse.Constants;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.ActionList;
import prefuse.action.RepaintAction;
import prefuse.action.assignment.ColorAction;
import prefuse.action.assignment.DataColorAction;
import prefuse.action.layout.CircleLayout;
import prefuse.action.layout.CollapsedStackLayout;
import prefuse.action.layout.GridLayout;
import prefuse.action.layout.Layout;
import prefuse.action.layout.RandomLayout;
import prefuse.action.layout.graph.ForceDirectedLayout;
import prefuse.activity.Activity;
import prefuse.controls.DragControl;
import prefuse.controls.PanControl;
import prefuse.controls.ZoomControl;
import prefuse.data.Graph;
import prefuse.data.Node;
import prefuse.data.Schema;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.LabelRenderer;
import prefuse.util.ColorLib;
import prefuse.visual.VisualItem;

public class PrefuseVisualizationAdapter implements VisualizationAdapter {

	private Graph graph;

	@Override
	public void drawGraph() {
		// -- 2. the visualization --------------------------------------------

		// add the graph to the visualization as the data group "graph"
		// nodes and edges are accessible as "graph.nodes" and "graph.edges"
		Visualization vis = new Visualization();
		vis.add("graph", graph);
		vis.setInteractive("graph.edges", null, false);

		// -- 3. the renderers and renderer factory ---------------------------

		// draw the "name" label for NodeItems
		LabelRenderer r = new LabelRenderer(LABEL);
		r.setRoundedCorner(8, 8); // round the corners

		// create a new default renderer factory
		// return our name label renderer as the default for all non-EdgeItems
		// includes straight line edges for EdgeItems by default
		vis.setRendererFactory(new DefaultRendererFactory(r));

		// -- 4. the processing actions ---------------------------------------
		ColorAction text = new ColorAction("graph.nodes", VisualItem.TEXTCOLOR,
				ColorLib.gray(0));
		// use light grey for edges
		ColorAction edges = new ColorAction("graph.edges",
				VisualItem.STROKECOLOR, ColorLib.gray(200));

		// create an action list containing all color assignments
		ActionList color = new ActionList();
		// color.add(fill);
		color.add(text);
		color.add(edges);

		// create an action list with an animated layout
		ActionList layout = new ActionList(Activity.INFINITY);
		layout.add(new ForceDirectedLayout("graph"));
		layout.add(new RepaintAction());

		// add the actions to the visualization
		vis.putAction("color", color);
		vis.putAction("layout", layout);

		// -- 5. the display and interactive controls -------------------------

		Display d = new Display(vis);
		d.setSize(720, 500); // set display size
		// drag individual items around
		d.addControlListener(new DragControl());
		// pan with left-click drag on background
		d.addControlListener(new PanControl());
		// zoom with right-click drag
		d.addControlListener(new ZoomControl());

		// -- 6. launch the visualization -------------------------------------

		// create a new window to hold the visualization
		JFrame frame = new JFrame("php Parse Example");
		// ensure application exits when window is closed
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(d);
		frame.pack(); // layout components in window
		frame.setVisible(true); // show the window

		// assign the colors
		vis.run("color");
		// start up the animated layout
		vis.run("layout");

	}

	@Override
	public void setNodes(Statement[] nodes) {

		graph = new Graph();
		graph.getNodeTable().addColumns(LABEL_SCHEMA);
		for (Statement node : nodes) {
			if (node != null) {
				Node n = graph.addNode();
				n.setString(LABEL, node.toString());
			}
		}

		for (int i = 0; i < graph.getNodeCount() - 1; i++) {
			graph.addEdge(graph.getNode(i), graph.getNode(i + 1));
		}
	}

	// ------------------------------------------------------------------------

	/** Label data field included in generated Graphs */
	public static final String LABEL = "label";
	/** Node table schema used for generated Graphs */
	public static final Schema LABEL_SCHEMA = new Schema();
	static {
		LABEL_SCHEMA.addColumn(LABEL, String.class, "");
	}

}
